package corn

import (
	"sync"
	"time"
)

// 1.注册任务和执行间隔
// 2.实现优雅退出
// 3.错误隔离，单个任务的panic不能影响其他任务

type Task struct {
	Dofunc func()        //任务执行函数
	Period time.Duration //间隔时间
	AtOnce bool          //是否立即开始执行
}

type Corn struct {
	quitChans []chan bool //任务退出channel列表
	sync.Mutex
	//stop      <-chan struct{} //退出
}

func NewCorn() *Corn {
	return &Corn{
		quitChans: make([]chan bool, 0),
	}
}

func (c *Corn) Register(task Task) {
	quit := make(chan bool, 0)
	go func(quit chan bool) {
		if task.AtOnce {
			task.Dofunc()
		}
		timer := time.NewTicker(task.Period)
		for {
			select {
			case <-timer.C:
				task.Dofunc()
			case <-quit:
				return
			}
		}
	}(quit)
	c.Lock()
	defer c.Unlock()
	c.quitChans = append(c.quitChans, quit)
}

func (c *Corn) Stop() {
	c.Lock()
	defer c.Unlock()
	for _, q := range c.quitChans {
		q <- true
	}
	c.quitChans = c.quitChans[:0]
}

var stdCorn *Corn
var once sync.Once

func init() {
	once.Do(func() {
		if stdCorn == nil {
			stdCorn = NewCorn()
		}
	})
}

func Register(task Task) {
	stdCorn.Register(task)
}

func Stop() {
	stdCorn.Stop()
}
